# -*- coding: utf-8 -*-
import math
import re
from time import time


class Color:
    RED = '\033[38;2;255;0;0m'
    GREEN = '\033[38;2;0;255;0m'
    YELLOW = '\033[38;2;255;255;0m'
    BLUE = '\033[38;2;0;0;255m'
    PURPLE = '\033[38;2;255;0;255m'
    CYAN = '\033[38;2;0;255;255m'
    WHITE = '\033[38;2;255;255;255m'
    RESET = '\033[0m'


class PasreArticle(object):

    def __init__(self, article_content):
        self.category_content = {}
        if not isinstance(article_content, str):
            article_content = str(article_content)
        paragraphs = article_content.split('\n')
        self.article_content = ''
        self.paragraphs = []
        for paragraph in paragraphs:
            if paragraph.strip() != "":
                self.paragraphs.append(paragraph.strip())
                self.article_content += paragraph.strip() + '\n'
        self.char_sums = len(self.article_content)
        self.abstract_sign = 0
        self.refer_sign = len(self.paragraphs)
        self.ArticleStruct = []

    def setSigns(self):
        self.setAbstractSign()
        self.setReferSign()

    def setAbstractSign(self):
        for index, paragraph in enumerate(self.paragraphs):
            paragraph = paragraph.replace(' ', '')
            if '摘要' in paragraph[0:4] and self.abstract_sign == 0:
                self.abstract_sign = index

    def setReferSign(self):
        positions = PasreArticle.find_all_substring_positions(self.article_content, '参考文献')
        if positions[-1] != -1 and positions[-1] / self.char_sums > 0.7:
            for index, paragraph in enumerate(self.paragraphs):
                paragraph = paragraph.replace(' ', '')
                if '参考文献' in paragraph and len(paragraph) < 10:
                    self.refer_sign = index

    def getParagrphByIndex(self, index):
        for item in self.ArticleStruct:
            if item['paragraph_index'] == index:
                return item
        return []

    def parse(self):
        paragraph_index = 0
        char_index = 0
        has_category = 0
        category_index = 0
        current_category_index = 0
        for index, paragraph in enumerate(self.paragraphs):
            paragraph = paragraph.replace('…', '').replace('....', '')
            paragraph_length = len(paragraph.strip())
            char_index += paragraph_length
            zh_count, zh_content = PasreArticle.count_zh(paragraph)
            current_category_position = len(paragraph.strip())
            if index <= self.abstract_sign and len(paragraph) < 140:
                self.ArticleStruct.append(
                    {
                        'content': paragraph,
                        'paragraph_index': paragraph_index,
                        'check': 0,
                        'type': 'uncheck',
                        'category_index': current_category_index
                    }
                )
                paragraph_index += 1
                continue
            if zh_content == '目录' and paragraph_length < 10:
                if has_category == 0:
                    current_category_position = char_index
                has_category = 1
                self.ArticleStruct.append(
                    {
                        'content': paragraph,
                        'paragraph_index': paragraph_index,
                        'check': 0,
                        'type': 'uncheck',
                        'category_index': current_category_index
                    }
                )
                paragraph_index += 1
                continue
            elif char_index - current_category_position <= 150 and index < self.refer_sign and index > self.abstract_sign and re.search(
                    '^(([(（]){1}(一|二|三|四|五|六|七|八|九|\d{1,2})([)）]){1})|^((一|二|三|四|五|六|七|八|九|\d{1,2})(.|。|,| ){1})',
                    paragraph) and len(zh_content) < 40 and len(paragraph) < 140 and zh_count >= 2:
                current_category_position = char_index
                self.ArticleStruct.append(
                    {
                        'content': paragraph,
                        'paragraph_index': paragraph_index,
                        'check': 0,
                        'type': 'category',
                        'category_index': category_index
                    }
                )
                current_category_index = category_index
                category_index += 1
                paragraph_index += 1
                continue
            elif index > self.abstract_sign and index < self.refer_sign and re.search(
                    '^(([(（]){1}(一|二|三|四|五|六|七|八|九|\d{1,2})([)）]){1})|^((一|二|三|四|五|六|七|八|九|\d{1,2})(.|。|,| ){1})',
                    paragraph) and len(zh_content) < 40 and len(paragraph) < 40 and zh_count >= 2:
                current_category_position = char_index
                self.ArticleStruct.append(
                    {
                        'content': paragraph,
                        'paragraph_index': paragraph_index,
                        'check': 0,
                        'type': 'category',
                        'category_index': category_index
                    }
                )
                current_category_index = category_index
                category_index += 1
                paragraph_index += 1
                continue
            elif index > self.abstract_sign and index < self.refer_sign and re.search(
                    '^第(一|二|三|四|五|六|七|八|九|十)+章.*$',
                    paragraph) and len(zh_content) < 40 and len(paragraph) < 40 and zh_count >= 2:
                current_category_position = char_index
                self.ArticleStruct.append(
                    {
                        'content': paragraph,
                        'paragraph_index': paragraph_index,
                        'check': 0,
                        'type': 'category',
                        'category_index': category_index
                    }
                )
                current_category_index = category_index
                category_index += 1
                paragraph_index += 1
                continue
            elif zh_count == 0 and len(paragraph) < 140 and index < self.refer_sign:
                self.ArticleStruct.append(
                    {
                        'content': paragraph,
                        'paragraph_index': paragraph_index,
                        'check': 0,
                        'type': 'uncheck',
                        'category_index': current_category_index
                    }
                )
                paragraph_index += 1
                continue
            elif index < self.abstract_sign and zh_count < 140:
                self.ArticleStruct.append(
                    {
                        'content': paragraph,
                        'paragraph_index': paragraph_index,
                        'check': 0,
                        'type': 'uncheck',
                        'category_index': current_category_index
                    }
                )
                paragraph_index += 1
                continue
            elif zh_content == '参考文献' and paragraph_length < 140:
                self.ArticleStruct.append(
                    {
                        'content': paragraph,
                        'paragraph_index': paragraph_index,
                        'check': 0,
                        'type': 'uncheck',
                        'category_index': current_category_index
                    }
                )
                paragraph_index += 1
                continue
            elif (
                    '关键词:' in paragraph or '关键词：' in paragraph) and paragraph_length < 40 and paragraph_length < 140:
                self.ArticleStruct.append(
                    {
                        'content': paragraph,
                        'paragraph_index': paragraph_index,
                        'check': 0,
                        'type': 'uncheck',
                        'category_index': current_category_index
                    }
                )
                paragraph_index += 1
                continue
            elif index > self.refer_sign and (
                    re.search('([\[|【|［]\d{1,3}[】|\]|］])', paragraph.strip()[0:4])) and self.len_count(paragraph) < 800:
                self.ArticleStruct.append(
                    {
                        'content': paragraph,
                        'paragraph_index': paragraph_index,
                        'check': 0,
                        'type': 'refer'
                    }
                )
                paragraph_index += 1
                continue
            elif index > self.refer_sign and (
                    re.search('([\[|【|［][a-zA-Z][】|\]|］])', paragraph.strip())) and self.len_count(paragraph) < 800:

                self.ArticleStruct.append(
                    {
                        'content': paragraph,
                        'paragraph_index': paragraph_index,
                        'check': 0,
                        'type': 'refer'
                    }
                )
                paragraph_index += 1
                continue
            elif ('本人所呈交的毕业论文' in paragraph or '本人郑重声明' in paragraph) and len(paragraph) < 200:
                self.ArticleStruct.append(
                    {
                        'content': paragraph,
                        'paragraph_index': paragraph_index,
                        'check': 0,
                        'type': 'uncheck',
                        'category_index': current_category_index
                    }
                )
                paragraph_index += 1
                continue
            elif ('原创性声明' in paragraph or '授权说明' in paragraph) and len(paragraph) < 200:
                self.ArticleStruct.append(
                    {
                        'content': paragraph,
                        'paragraph_index': paragraph_index,
                        'check': 0,
                        'type': 'uncheck',
                        'category_index': current_category_index
                    }
                )
                paragraph_index += 1
                continue
            elif ('附录示例' in paragraph) and len(paragraph) < 50:
                self.ArticleStruct.append(
                    {
                        'content': paragraph,
                        'paragraph_index': paragraph_index,
                        'check': 0,
                        'type': 'uncheck',
                        'category_index': current_category_index
                    }
                )
                paragraph_index += 1
                continue
            elif ('致谢' in paragraph) and len(paragraph) < 10:
                self.ArticleStruct.append(
                    {
                        'content': paragraph,
                        'paragraph_index': paragraph_index,
                        'check': 0,
                        'type': 'uncheck',
                        'category_index': current_category_index
                    }
                )
                paragraph_index += 1
                continue
            elif len(paragraph) < 45:
                self.ArticleStruct.append(
                    {
                        'content': paragraph,
                        'paragraph_index': paragraph_index,
                        'check': 0,
                        'type': 'uncheck',
                        'category_index': current_category_index
                    }
                )
                paragraph_index += 1
                continue
            else:
                self.ArticleStruct.append(
                    {
                        'content': paragraph,
                        'paragraph_index': paragraph_index,
                        'check': 1,
                        'type': 'content',
                        'category_index': current_category_index
                    }
                )
                paragraph_index += 1

    @staticmethod
    def count_zh(paragraph):
        count = 0
        zh = ''
        for s in paragraph:
            if '\u4e00' <= s <= '\u9fa5':
                count += 1
                zh += s
        return count, zh

    @staticmethod
    def find_all_substring_positions(string, substring):
        positions = []
        start = 0
        while True:
            start = string.find(substring, start)
            if start == -1:
                if positions == []:
                    positions.append(start)
                break
            positions.append(start)
            start += 1
        return positions

    # @staticmethod
    # def cut_paragraph(paragraph):
    #     sub_paragraph = []
    #     return sub_paragraph

    @staticmethod
    def len_count(content):
        pattern = re.compile(r'[\u4e00-\u9fa5]|[a-zA-Z0-9\.,!?]')
        # 使用正则表达式查找所有匹配项
        matches = pattern.findall(content)
        # 计算总字数，中文字符算4个，其他字符算1个
        count = sum(4 if re.match(r'[\u4e00-\u9fa5]', char) else 1 for char in matches)
        return count

    @staticmethod
    def split_text(paragraph):
        total = PasreArticle.len_count(paragraph['content'])
        if total >= 600 and total <= 1600:
            return [paragraph]
        if total < 600:
            paragraph['type'] = 'uncheck'
            return [paragraph]
        res_list = []
        paragraphs = paragraph['content'].split('\n')
        current_index = paragraph['paragraph_index']
        current_step = 0
        for index, item in enumerate(paragraphs):
            if index == current_step:
                if PasreArticle.len_count(item) <= 1600:
                    current_content = item
                    while PasreArticle.len_count(current_content) < 800 and current_step < len(
                            paragraphs) - 1 and PasreArticle.len_count(current_content) + PasreArticle.len_count(
                        paragraphs[current_step + 1]) < 1600:
                        current_step += 1
                        current_content += paragraphs[current_step] + '\n'
                    current_paragraph = paragraph.copy()
                    current_paragraph['content'] = current_content
                    current_paragraph['paragraph_index'] = current_index + 1
                    res_list.append(current_paragraph)
                    current_step += 1
                else:
                    current_sentence_step = 0
                    sentences = PasreArticle.SplitSentences('[。！?!.,，]', item)
                    for sentence_index, sentence in enumerate(sentences):
                        if sentence_index == current_sentence_step:
                            current_content = sentence
                            while PasreArticle.len_count(current_content) < 1000 and current_sentence_step < len(
                                    sentences) - 1 and PasreArticle.len_count(
                                current_content) + PasreArticle.len_count(
                                sentences[current_sentence_step + 1]) < 2000:
                                current_sentence_step += 1
                                current_content += sentences[current_sentence_step]
                            insert_paragraph = {}
                            insert_paragraph['content'] = current_content
                            insert_paragraph['type'] = 'content'
                            res_list.append(insert_paragraph)
                            current_sentence_step += 1
                    current_step += 1
        return res_list

    def parseCategoryContent(self):
        self.category_content = {}
        for item in self.ArticleStruct:
            if item['type'] == 'category':
                if not item['category_index'] in self.category_content.keys():
                    self.category_content[item['category_index']] = {}
                    self.category_content[item['category_index']]['content'] = item['content'] + '\n'
                    self.category_content[item['category_index']]['uncheck'] = len(item['content'])
            if item['type'] in ['content', 'uncheck']:
                if not item['category_index'] in self.category_content.keys():
                    self.category_content[item['category_index']] = {}
                    self.category_content[item['category_index']]['content'] = item['content'] + '\n'
                    if item['type'] == 'uncheck':
                        self.category_content[item['category_index']]['uncheck'] = len(item['content'])
                else:
                    self.category_content[item['category_index']]['content'] += item['content'] + '\n'
                    if item['type'] == 'uncheck':
                        try:
                            self.category_content[item['category_index']]['uncheck'] += len(item['content'])
                        except Exception as e:
                            print(self.category_content[item['category_index']])

    def insertParagraphs(self):
        insert_paragraphs = []
        category_list = []
        for item in self.ArticleStruct:
            if item['type'] in ['uncheck', 'refer']:
                if item['type'] == 'uncheck':
                    if item['category_index'] not in category_list:
                        if item['category_index'] != 0:
                            category_list.append(item['category_index'])
                            tmp = item.copy()
                            tmp['content'] = self.category_content[item['category_index']]['content']
                            tmp['type'] = self.jugdeType(self.category_content[item['category_index']])
                            insert_paragraphs.append(tmp)
                        else:
                            insert_paragraphs.append(item)
                            self.category_content[0]['content'] = self.category_content[0]['content'].replace(
                                item['content'], '')
                else:
                    insert_paragraphs.append(item)
            if item['type'] in ['category', 'content']:
                if item['category_index'] not in category_list:
                    category_list.append(item['category_index'])
                    item['content'] = self.category_content[item['category_index']]['content']
                    item['type'] = 'content'
                    if len(item['content']) > 0:
                        if len(item['content']) > 150:
                            subs = PasreArticle.split_text(item)
                            insert_paragraphs.extend(subs)
                        else:
                            item['type'] = 'uncheck'
                            insert_paragraphs.append(item)
                # else:
                #     if self.isParagraphByCateIndex(item['category_index'], insert_paragraphs):
                #         item['content'] = self.category_content[item['category_index']]
                #         item['type'] = 'content'
                #         if len(item['content']) > 0:
                #             if len(item['content']) > 150:
                #                 subs = PasreArticle.split_text(item)
                #                 insert_paragraphs.extend(subs)
                #             else:
                #                 item['type'] = 'uncheck'
                #                 insert_paragraphs.append(item)
        return insert_paragraphs

    def jugdeType(self, info):
        if info['uncheck'] == 0:
            return 'content'
        else:
            if round(info['uncheck'] / len(info['content']), 2) < 0.5:
                return 'content'
            else:
                return 'uncheck'

    def isParagraphByCateIndex(self, cateIndex, insert_paragraphs):
        for item in insert_paragraphs:
            if item['category_index'] == cateIndex:
                if item['type'] == 'uncheck':
                    return True
        return False

    def run(self):
        self.setSigns()
        self.parse()
        return 0

    @staticmethod
    def SplitSentences(splitstring, sentecne):
        sentences = re.split(splitstring, sentecne)
        sentences.append("")
        sentences = ["".join(i) for i in zip(sentences[0::2], sentences[1::2])]
        return sentences


if __name__ == '__main__':
    with open('/home/SameReportApi/app/libs/article.txt', 'r') as f:
        text = f.read()
    article_content = text
    bot = PasreArticle(article_content)
    insert_paragraphs = bot.run()

    # category_content = {}
    # cate_content = ''
    # for item in bot.ArticleStruct:
    #     if item['type'] == 'category':
    #         if not item['category_index'] in category_content.keys():
    #             category_content[item['category_index']] = item['content'] + '\n'
    #     if item['type'] in ['content', 'uncheck']:
    #         if not item['category_index'] in category_content.keys():
    #             category_content[item['category_index']] = item['content'] + '\n'
    #         category_content[item['category_index']] += item['content'] + '\n'
    # # for item in category_content.keys():
    # #     print(category_content[item])
    # #     print('\n')
    # category_list = []
    # insert_paragraphs = []
    #
    # for item in bot.ArticleStruct:
    #     if item['type'] in ['uncheck', 'refer']:
    #         if item['type'] == 'uncheck':
    #             if item['category_index'] not in category_list:
    #                 insert_paragraphs.append(item)
    #         else:
    #             insert_paragraphs.append(item)
    #     if item['type'] in ['category', 'content', 'uncheck']:
    #         if item['category_index'] not in category_list:
    #             category_list.append(item['category_index'])
    #             item['content'] = category_content[item['category_index']]
    #             item['type'] = 'content'
    #             start_index = item['paragraph_index']
    #             if len(item['content']) > 0:
    #                 if len(item['content']) > 150:
    #                     subs = PasreArticle.split_text(item)
    #                     insert_paragraphs.extend(subs)
    #                 else:
    #                     item['type'] = 'uncheck'
    #                     insert_paragraphs.append(item)
    # for item in insert_paragraphs:
    #     if len(item['content']) > 0:
    #         if item['type'] == 'refer':
    #             print(Color.YELLOW + item['content'] + Color.RESET)
    #         if item['type'] == 'uncheck':
    #             print(Color.GREEN + item['content'] + Color.RESET)
    #         if item['type'] == 'content':
    #             print(Color.RED + item['content'] + Color.RESET)
    #         if item['type'] == 'category':
    #             print(Color.BLUE + item['content'] + Color.RESET)
    #         print('-------------------------------------------------------')
